package com.terren.statistic.execute;

import java.io.File;
import java.io.FileOutputStream;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.terren.statistic.common.entity.Documents;
import com.terren.statistic.common.entity.SysConfig;
import com.terren.statistic.common.util.CommonUtil;
import com.terren.statistic.common.util.DateUtil;
import com.terren.statistic.common.util.FileOperateUtils;
import com.terren.statistic.common.util.LogUtil;
import com.terren.statistic.db.entity.CustomizedStat;
import com.terren.statistic.db.entity.EventTopic;
import com.terren.statistic.db.entity.EventTopicKeyword;
import com.terren.statistic.db.entity.EventTopicStatis;
import com.terren.statistic.db.entity.TopicStatis;
import com.terren.statistic.db.service.CustomizedStatService;
import com.terren.statistic.db.service.EventTopicService;
import com.terren.statistic.db.service.EventTopicStatisService;
import com.terren.statistic.execute.excel.KeywordExcel;
import com.terren.statistic.execute.excel.TopicExcel;

/***
 * https://blog.csdn.net/cs373616511/article/details/80325458 excel文件压缩
 * @author admin
 *
 */
public class EventTopicStatistic extends BasicStatistic{
	
	private static Logger logger = LogUtil.getLogger(EventTopicStatistic.class);
	
	private String api = "http://[RIDXHOST]:[RIDXPORT]/s/v1/search?q=[KW]&ctype=[CTYPE]&ps=[PS]&pe=[PE]&p=1&field=title,content";	
	private long totalUv = 0;
	private long totalPv = 0;
	private static String folder;
	
	EventTopicService eventTopicService;
	CustomizedStatService customizedStatService;
	EventTopicStatisService eventTopicStatisService;

	public EventTopicStatistic() {
		super();
		eventTopicService = CommonUtil.getBean(EventTopicService.class);
		customizedStatService = CommonUtil.getBean(CustomizedStatService.class);
		eventTopicStatisService = CommonUtil.getBean(EventTopicStatisService.class);
	}

	public void getData() {
		try {
			List<EventTopic> tipicList = eventTopicService.getTopicList(null);
			for (EventTopic topic : tipicList) {
				EventTopicKeyword param = new EventTopicKeyword();
				param.setTopicId(topic.getTopicId());
				folder = "file_" + topic.getTopicId();
				path = SysConfig.OUTSIDE_PATH + folder + File.separator;
				List<EventTopicKeyword> keywordList = eventTopicService.getTopicKeywordList(param);
				for(EventTopicKeyword kw : keywordList) {
					if(kw.getStartTime()==null) {
						kw.setStartTime(topic.getStartTime());
					}
					if(kw.getEndTime()==null) {
						kw.setEndTime(topic.getEndTime());
					}
					
					getDataForCtype(kw, OFFICIAL_SITE);
					getDataForCtype(kw, PORTAL_SITE);
					saveAnaData(kw.getStartTime(), kw.getEndTime(), kw.getKeyword(),kw.getKeyid());
					if(topic.getType()==1) {
						createKeyExcelFile(kw);//按关键词保存到csv文件
					}
					eventTopicService.updateTopicKeywordStatus(kw);
				}
				createTopicExcelFile(topic);
				//将Excel文件压缩到zip文件
				String zipPath = SysConfig.OUTSIDE_PATH + folder +".zip";
				FileOutputStream fos1 = new FileOutputStream(new File(zipPath));
				Boolean flag = FileOperateUtils.toZip(path, fos1, true);
				File directory = new File(path);
				if(directory.exists() && flag) {
					FileUtils.deleteDirectory(directory);
					topic.setPath(zipPath);
					topic.setStatus(1);
				}else {
					topic.setStatus(9);
				}
				eventTopicService.updateTopicStatus(topic);
				
			}
		} catch (Exception e) {
			logger.error("EventTopicStatistic.getData() error " + e.getMessage());
			e.printStackTrace();
		}
	}

	private void getDataForCtype(EventTopicKeyword kw, short cType) {
		docList = new ArrayList<Documents>();
		String keyword = kw.getKeyword();
		String startTime = kw.getStartTime();
		String endTime = kw.getEndTime();
		logger.info("Keyword: " + keyword + ", ctype: " + cType);
		try {
			long st = System.currentTimeMillis();
			String cTypeStr = String.valueOf(cType);
			int articles = 0;
			totalUv = 0;
			totalPv = 0;
			int offset = 0;
			// if(cType == 3 || cType == 4) {
			while (true) {
				try {
					String jsonStr = getDataByUrl(api, cTypeStr, keyword, startTime, endTime, offset);
					// System.out.println(jsonStr);
					JSONObject jObj = JSONObject.parseObject(jsonStr);
					articles = jObj.getIntValue("total");
					parseJson(jsonStr);
					offset += SysConfig.LIMIT;
					if (offset >= articles)
						break;
				} catch (SocketTimeoutException se) {
					logger.error("SocketTimeoutException, Retry!" + se.getMessage());
					continue;
				}
			}
			saveCustomizedStats(cType, keyword);//数据入库
			long et = System.currentTimeMillis();
			logger.info("keyword: " + keyword + ", cType: " + cType + ", articles: " + articles + ", totalPv: " + totalPv + ", totalUv: " + totalUv + ", usage: " + (et - st) / 1000 + "(s).");
			if(SysConfig.FILE_CREATE) {
				if (fileFormat.equals("2")) {
					exportJson(cType, startTime, endTime, keyword);
				}else if (fileFormat.equals("3")) {
					exportHtml(cType, startTime, endTime, keyword);	
				}else if (fileFormat.equals("4")) {
					exportTxt(cType, startTime, endTime, keyword);
				}else {
					exportExcel(cType, startTime, endTime, keyword);
				}
			}
		} catch (Exception e) {
			logger.error("getDataForCtype error "+e.getMessage());
			e.printStackTrace();
		}
	}


	private void parseJson(String jsonStr) {
		JSONObject jsonObj = JSONObject.parseObject(jsonStr);
		JSONArray jArr = jsonObj.getJSONArray("documents");
		long uv = 0;
		long pv = 0;
		for (int i = 0; i < jArr.size(); i++) {
			Documents doc = JSON.toJavaObject(jArr.getJSONObject(i), Documents.class);
			docList.add(doc);
			uv += doc.getUv();
			pv += doc.getPv();
		}
		totalUv += uv;
		totalPv += pv;
	}
	
	private void saveCustomizedStats(short cType, String keyword) throws Exception {
		List<CustomizedStat> list = new ArrayList<CustomizedStat>();
		for(Documents doc : docList) {
			CustomizedStat param = new CustomizedStat();
			Integer day = Integer.parseInt(DateUtil.formatDateString(doc.getPublishDay(), "yyyy-MM-dd HH:mm:ss", "yyyyMMdd"));
			param.setDay(day);
			param.setSource(doc.getCustomer());
			param.setUrlid(doc.getId());
			param.setUrl(doc.getUrl());
			param.setTitle(doc.getTitle());
			param.setUv(doc.getUv());
			param.setKeyword(keyword);
			param.setCtype(cType);
			list.add(param);
		}
		if(CollectionUtils.isNotEmpty(list)) {
			customizedStatService.saveCustomizedStats(list);
		}
	}

	private void saveAnaData(String startDate, String endDate, String keyword, long keyid) throws Exception{
		EventTopicKeyword param = new EventTopicKeyword();
		param.setStartTime(DateUtil.formatDateString(startDate, "yyyy-MM-dd", "yyyyMMdd"));
		param.setEndTime(DateUtil.formatDateString(endDate, "yyyy-MM-dd", "yyyyMMdd"));
		param.setKeyword(keyword);
		param.setCtype(OFFICIAL_SITE);
		List<CustomizedStat> offList = customizedStatService.getKeywordStatis(param);
		int offuv = offList.stream().mapToInt(e->e.getVisitCnt()).sum();
		int offCnt = offList.stream().mapToInt(e->e.getArticleCnt()).sum();
		EventTopicStatis offt = new EventTopicStatis();
		offt.setArticleCnt(offCnt);
		offt.setUv(offuv);
		offt.setCtype(OFFICIAL_SITE);
		offt.setKeyid(keyid);
		eventTopicStatisService.addEventTopicStatis(offt);
		
		param.setCtype(PORTAL_SITE);
		List<CustomizedStat> porList = customizedStatService.getKeywordStatis(param);
		int poruv = porList.stream().mapToInt(e->e.getVisitCnt()).sum();
		int porCnt = porList.stream().mapToInt(e->e.getArticleCnt()).sum();
		EventTopicStatis port = new EventTopicStatis();
		port.setArticleCnt(porCnt);
		port.setUv(poruv);
		port.setCtype(PORTAL_SITE);
		port.setKeyid(keyid);
		eventTopicStatisService.addEventTopicStatis(port);	
	}
	
	/**
	 * 创建关键词Excel文件
	 * @param startDate
	 * @param endDate
	 * @param keyword
	 * @throws Exception
	 */
	private void createKeyExcelFile(EventTopicKeyword kw) throws Exception {
		EventTopicKeyword param = new EventTopicKeyword();
		param.setStartTime(DateUtil.formatDateString(kw.getStartTime(), "yyyy-MM-dd", "yyyyMMdd"));
		param.setEndTime(DateUtil.formatDateString(kw.getEndTime(), "yyyy-MM-dd", "yyyyMMdd"));
		param.setKeyword(kw.getKeyword());
		List<CustomizedStat> offList = customizedStatService.getKeywordOffStatis(param);
		List<CustomizedStat> porList = customizedStatService.getKeywordPorStatis(param);
		String name = kw.getName();
		if(StringUtils.isNoneBlank(name)) {
			name = name.trim();
		}else {
			name = kw.getKeyword();
		}
		String fileName = CommonUtil.StringFilter(name)+"_"+ param.getStartTime() + "_" + param.getEndTime();
		KeywordExcel excel = new KeywordExcel();
		excel.createExcel(offList, porList, fileName, path);
	}
	
	/**
	 * 创建主题Excel文件
	 * @param topic
	 * @return
	 * @throws Exception
	 */
	private void createTopicExcelFile(EventTopic topic) throws Exception {
		List<TopicStatis> list = eventTopicStatisService.getTopicStatis(topic);
		TopicExcel te = new TopicExcel();
		te.createExcel(list, CommonUtil.StringFilter("_" + topic.getName())+"_"+ topic.getStartTime() + "_" + topic.getEndTime(), path);
	};
	/*
	private void writeSummaryFile(String startDate, String endDate, String keyword) throws Exception {
		EventTopicKeyword param = new EventTopicKeyword();
		param.setStartTime(DateUtil.formatDateString(startDate, "yyyy-MM-dd", "yyyyMMdd"));
		param.setEndTime(DateUtil.formatDateString(endDate, "yyyy-MM-dd", "yyyyMMdd"));
		param.setKeyword(keyword);
		
		List<CustomizedStat> offList = customizedStatService.getKeywordOffStatis(param);
		String fileNameOff = path + "stat_"+CommonUtil.StringFilter(keyword)+"_ctype0_" + startDate + "_" + endDate + ".csv";
		File txtFileOff = new File(fileNameOff);
		if (mkdir(txtFileOff)) {
			// 用OutputStreamWriter 替代 FileWriter，解决写UTF8格式文件的问题
			// FileWriter fw = new FileWriter(nodesFile);
			OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(txtFileOff), "GBK");
			BufferedWriter bw = new BufferedWriter(fw);
			bw.append("日期").append(",").append("网站名称").append(",").append("发稿数").append(",").append("访客数").append(System.lineSeparator());
			for (CustomizedStat ts : offList) {
				bw.append(ts.getDay()+"").append(",");
				bw.append(ts.getSource()).append(",");
				bw.append(ts.getArticleCnt()+"").append(",");
				bw.append(ts.getVisitCnt()+"").append(System.lineSeparator());
			}
			bw.close();
			fw.close();
		}
		
		List<CustomizedStat> porList = customizedStatService.getKeywordPorStatis(param);
		String fileNamePor = path + "stat_"+CommonUtil.StringFilter(keyword)+"_ctype1_" + startDate + "_" + endDate + ".csv";
		File txtFilePor = new File(fileNamePor);
		if (mkdir(txtFilePor)) {
			// 用OutputStreamWriter 替代 FileWriter，解决写UTF8格式文件的问题
			// FileWriter fw = new FileWriter(nodesFile);
			OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(txtFilePor), "GBK");
			BufferedWriter bw = new BufferedWriter(fw);
			bw.append("日期").append(",").append("网站名称").append(",").append("发稿数").append(",").append("评论数").append(System.lineSeparator());
			for (CustomizedStat ts : porList) {
				bw.append(ts.getDay()+"").append(",");
				bw.append(ts.getSource()).append(",");
				bw.append(ts.getArticleCnt()+"").append(",");
				bw.append(ts.getCommentCnt()+"").append(System.lineSeparator());
			}
			bw.close();
			fw.close();
		}
	}
	*/
}
